package com.spark.market.service.manager.mq.producer;

import com.spark.market.api.mq.ItemStockMqMessage;
import com.spark.market.service.manager.mq.MQProducer;
import com.spark.market.common.utils.AssertUtils;

import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zwd
 * @date 2021/6/27
 * @email zwd@hhh.com
 */
@Component
public class ItemStockProducerManager{
    /**
     * 异步更新库存队列名称
     */
    @Value("${mq.producer.item.stock.queue-name}")
    private String itemStockQueueName;
    /**
     * 异步更新库存路由key
     */
    @Value("${mq.producer.item.stock.routing-name}")
    private String itemStockRoutingKey;
    /**
     * 异步更新库存交换器名称
     */
    @Value("${mq.producer.item.stock.exchange-name}")
    private String itemStockExchangeName;
    /**
     * 异步更新库存死信队列名称
     */
    @Value("${mq.producer.item.stock.dead-queue-name}")
    private String itemStockDeadQueueName;
    /**
     * 异步更新库存死信队列路由key
     */
    @Value("${mq.producer.item.stock.dead-queue-routing-name}")
    private String ItemStockDeadRoutingKey;
    /**
     * 异步更新库存死信队列交换器名称
     */
    @Value("${mq.producer.item.stock.dead-queue-exchange-name}")
    private String ItemStockDeadExchangeName;

    @Resource
    private MQProducer mqProducer;

    public void sendItemStockMsg(ItemStockMqMessage itemStockMqMessage) {
        AssertUtils.isNotNull(itemStockMqMessage.getItemId(), "itemId is null");
        AssertUtils.isNotNull(itemStockMqMessage.getAmount(), "amount is null");
        mqProducer.sendMessage(itemStockExchangeName, itemStockRoutingKey, itemStockMqMessage);
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        //声明死信队列（Fanout类型的exchange）
        Queue deadQueue = new Queue(itemStockDeadQueueName, true);
        // 死信队列交换机
        FanoutExchange deadExchange = new FanoutExchange(ItemStockDeadExchangeName);
        rabbitAdmin.declareQueue(deadQueue);
        rabbitAdmin.declareExchange(deadExchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(deadQueue).to(deadExchange));

        // 更新库存交换机
        DirectExchange exchange = new DirectExchange(itemStockExchangeName);

        //声明发送优惠券的消息队列（Direct类型的exchange）
        Queue itemStockQueue = queue(itemStockQueueName);
        rabbitAdmin.declareQueue(itemStockQueue);
        rabbitAdmin.declareExchange(exchange);
        rabbitAdmin.declareBinding(BindingBuilder.bind(itemStockQueue).to(exchange).with(itemStockRoutingKey));

        return rabbitAdmin;
    }

    public Queue queue(String name) {
        Map<String, Object> args = new HashMap<>();
        // 设置死信队列
        args.put("x-dead-letter-exchange", itemStockDeadQueueName);
        args.put("x-dead-letter-routing-key", ItemStockDeadRoutingKey);
        // 设置消息的过期时间， 单位是毫秒
        args.put("x-message-ttl", 5000);

        // 是否持久化
        boolean durable = true;
        // 仅创建者可以使用的私有队列，断开后自动删除
        boolean exclusive = false;
        // 当所有消费客户端连接断开后，是否自动删除队列
        boolean autoDelete = false;
        return new Queue(name, durable, exclusive, autoDelete, args);
    }
}
